/* $Id: log.cc jjs $ */
/*
   Copyright (C) 2007 by Jurjen Stellingwerff <jurjen@stwerff.xs4all.nl>
   Part of the Moros Project http://moros.sourceforge.net/

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2 or any
   later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY.

   See the COPYING file for more details.
*/

#define DEBUG_ROUTINE "log"

#include <stdio.h>
#include <iostream>
#include <sstream>
#include "log.h"
#include "util.h"
#include "hashtable.h"

using namespace std;

FILE *log_file=stderr;
int dbg_genlevel=0;
hashtable<const char,int> dbg_hash(100);
string dbg_filename;

void dbg_init(const char *file) {
    dbg_filename=filename(file);
    log_file=fopen(dbg_filename.c_str(), "a");
    if (log_file==NULL) {
        std::cerr << "Could not open the logfile: " << dbg_filename << std::endl;
        log_file=stderr;
    }
}

void dbg_relink() {
    fclose(log_file);
    log_file=fopen(dbg_filename.c_str(), "a");
    if (log_file==NULL) {
        std::cerr << "Could not open the logfile: " << dbg_filename << std::endl;
        log_file=stderr;
    }
}

std::string month[]= {
    "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};

std::string dbg_time() {
    time_t now=time(NULL);
    struct tm *time=localtime(&now);
    std::ostringstream res;
    res << month[time->tm_mon] << "" <<
        time->tm_mday << " " <<
        time->tm_hour << ":" <<
        time->tm_min << ":" <<
        time->tm_sec;
    return res.str();
}

void dbg_log(const int prio, const char *routine, const char *format, ...) {
    int *priop=dbg_hash[routine];
    int cprio=dbg_genlevel;
    va_list args;
    va_start (args, format);
    if (priop) cprio=*priop;
    if (prio==DEBUG_ERROR && log_file != stderr) {
        fprintf (stderr, "%s %s: ERROR ",  dbg_time().c_str(), routine);
        vfprintf (stderr, format, args);
        fprintf (stderr, "\n");
        fflush(stderr);
    } else if (cprio>=prio) {
        fprintf (log_file, "%s %s: ",  dbg_time().c_str(), routine);
        if (prio==DEBUG_ERROR) fprintf(log_file, "ERROR ");
        vfprintf (log_file, format, args);
        fprintf (log_file, "\n");
        // if (prio<=DEBUG_STATE)
        fflush(log_file);
    }
    va_end (args);
}

void dbg_level(const int prio, const char *routine) {
    if (routine==0) {
        dbg_genlevel=prio;
    } else {
        const char *old_key;
        int *old_prio;
        int *new_prio=(int*)malloc(sizeof(int));
        if (dbg_hash.lookup_extended(routine, &old_key, &old_prio)) {
          dbg_hash.insert(routine, new_prio);
          free(old_prio);
        } else dbg_hash.insert(routine, new_prio);
    }
}
